export default class myAudioContext {
    constructor() {
        this.audioCtx = null
        this.drawVisual
    }
    start(type, _source, canvas) {
        this.audioCtx = new(window.AudioContext || window.webkitAudioContext)();
        let source
        //创建一个新的 关联 对象
        if (type == 'getUserAudio') {
            source = this.audioCtx.createMediaStreamSource(_source);
        } else {
            source = this.audioCtx.createMediaElementSource(_source);

        }
        let canvasCtx = canvas.getContext('2d')




        var analyser = this.audioCtx.createAnalyser();
        analyser.minDecibels = -90; //意思是收集 最低分贝 0 ~ -100
        analyser.maxDecibels = -10; //结果范围的最大值 -100 ~ 0
        analyser.smoothingTimeConstant = 0.8; //分析帧的平均常数 0-1  默认值为 0.8

        source.connect(analyser);
        let fftSizeValue = 5 // 5 ~ 15
        analyser.fftSize = Math.pow(2, fftSizeValue);
        var bufferLength = analyser.frequencyBinCount;
        var dataArray = new Uint8Array(bufferLength);
        // source.connect(audioCtx.destination);


        let WIDTH = canvas.width
        let HEIGHT = canvas.height
        console.log('bufferLength', bufferLength)
        let THIS = this
        // 下面是画图的
        function getByteFrequencyData() {
            THIS.drawVisual = requestAnimationFrame(getByteFrequencyData);
            analyser.getByteFrequencyData(dataArray);

            canvasCtx.fillStyle = 'rgb(0, 0, 0)';
            canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);

            var barWidth = (WIDTH / bufferLength) * 0.5;
            var barHeight;
            var x = 0;

            for (var i = 0; i < bufferLength; i++) {
                barHeight = dataArray[i];

                canvasCtx.fillStyle = 'rgb(' + (barHeight + 100) + ',50,50)';
                canvasCtx.fillRect(x, HEIGHT - barHeight / 2, barWidth, barHeight / 2);
                /*  
                context.fillRect(x,y,width,height);
                x    矩形左上角的 x 坐标
                y    矩形左上角的 y 坐标
                width    矩形的宽度，以像素计
                height    矩形的高度，以像素计
                */

                x += barWidth + 1;
            }
        };

        function getByteTimeDomainData() {
            THIS.drawVisual = requestAnimationFrame(getByteTimeDomainData);
            analyser.getByteTimeDomainData(dataArray);

            canvasCtx.fillStyle = 'rgb(200, 200, 200)';
            canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);

            canvasCtx.lineWidth = 2;
            canvasCtx.strokeStyle = 'rgb(0, 0, 0)';

            var sliceWidth = WIDTH * 1.0 / bufferLength;
            var x = 0;

            canvasCtx.beginPath();
            for (var i = 0; i < bufferLength; i++) {
                let v = dataArray[i] / 128.0,
                    y = v * HEIGHT / 2;

                if (i === 0)
                    canvasCtx.moveTo(x, y);
                else
                    canvasCtx.lineTo(x, y);

                x += sliceWidth;
            }

            canvasCtx.lineTo(canvas.width, canvas.height / 2);
            canvasCtx.stroke();
        };
        if (0) {
            getByteTimeDomainData()
        } else {
            getByteFrequencyData()
        }


    }


    close = () => {
        if(!this.audioCtx)return
        cancelAnimationFrame(this.drawVisual)
        this.audioCtx.close()
        this.audioCtx = null
    }
}




/*
AnalyserNode.fftSize
一个无符号长整形(unsigned long)的值，代表了用于计算频域信号时使用的 FFT (快速傅里叶变换) 的窗口大小。
 属性的值必须是从32到32768范围内的2的非零幂; 其默认值为2048.

AnalyserNode.frequencyBinCount 只读
一个无符号长整形(unsigned long)的值, 值为fftSize的一半。这通常等于将要用于可视化的数据值的数量。

AnalyserNode.minDecibels
是一个双精度值，表示FFT分析频域数据并转换为无符号字节值时，对输入的功率数据的最小阈值 - 基本上，它限定了调用getByteFrequencyData()时结果范围的最小值

AnalyserNode.maxDecibels
是一个双精度值，表示FFT分析频域数据并转换为无符号字节值时，对输入的功率数据的最大阈值 - 基本上，它限定了调用getByteFrequencyData()时结果范围的最大值

AnalyserNode.smoothingTimeConstant
是一个双精度浮点型(double)的值，表示最后一个分析帧的平均常数 — 基本上，它随时间使值之间的过渡更平滑。

AnalyserNode.getFloatFrequencyData()
将当前频域数据拷贝进Float32Array数组。

AnalyserNode.getByteFrequencyData()
将当前频域数据拷贝进Uint8Array数组（无符号字节数组）。

AnalyserNode.getFloatTimeDomainData()
将当前波形，或者时域数据拷贝进Float32Array数组。

AnalyserNode.getByteTimeDomainData()
将当前波形，或者时域数据拷贝进 Uint8Array数组（无符号字节数组）。 
*/